package com.dd.keel.core.common.shutdown;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dd.keel.core.common.shutdown.protocol.Protocol;
import com.dd.keel.core.common.shutdown.protocol.ProtocolFactory;
import com.dd.keel.core.common.shutdown.protocol.ShutdownProtocol;

/**
 * Shutdown server
 * @author Kevin.XU
 *
 */
public class ShutdownServer implements Runnable{
	
	final static private Logger LOGGER = LoggerFactory.getLogger(ShutdownServer.class);
	
	String shutdownServerName = null;
	ServerSocket shutdownServer = null;
	Shutdownable shutdownableObj = null;
	int port = 0;
	static int num = 0;
	boolean acceptable = true;
	
	public ShutdownServer(String shutdownServerName,Shutdownable shutdownableObj,int shutdown_port)
	{
		this.shutdownServerName = shutdownServerName;
		this.shutdownableObj = shutdownableObj;
		port = shutdown_port;
	}
	
	public void start()
	{
		++num;
		Thread thread = new Thread(this,"ShutdownServer-"+shutdownServerName+"-"+num);
		thread.start();
	}
	
	public void run() {
		
        try{
        	LOGGER.info( "Shutdown listener bind on {}", port );
        	shutdownServer = new ServerSocket(port);
        	System.out.println( shutdownServer.getInetAddress().toString() );
        } catch (BindException e) {
        	// 如果端口已被占用，则退出，并提示
        	LOGGER.error("Port Address already in use! System exit!", e);
        	System.out.println("Port Address already in use! System exit!");
        	System.exit(1);
        }catch(Exception ex){
        	LOGGER.error( ex.getMessage(), ex );
        }
        if(shutdownServer!=null)
        {
            Socket clientSocket = null;
            while(acceptable)
            {
            	PrintWriter out = null;
            	BufferedReader in = null;
                try{
                	LOGGER.info( "Shutdown listener is waitting client ... " );
                	clientSocket = shutdownServer.accept();
                	LOGGER.info( "Shutdown listener receive client: {}", clientSocket.getRemoteSocketAddress().toString() );
                	out = new PrintWriter(clientSocket.getOutputStream(), true);
                	in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                	String inputLine, outputLine;
                	Protocol protocol = ProtocolFactory.getProtocol(ProtocolFactory.SHUTDOWN_PROTOCOL);
                    
                	while( (inputLine = in.readLine()) != null )
                	{
                		outputLine = protocol.processInput(inputLine);
                		LOGGER.info( "Shutdown server reply : {}", outputLine );
                		out.println(outputLine);
                        if ( protocol.getState() == ShutdownProtocol.SENTBYE )
                        {
                        	LOGGER.info( "Shutdown server begin to shutdown all services ... " );
                        	shutdownableObj.shutdown();
                        	acceptable = false;
                        }
                	}
                }catch(Exception ex){
                	LOGGER.error( ex.getMessage(), ex );
                }finally{
                	try{
                		out.close();
                	}catch(Exception e){
                		e.printStackTrace();
                	}
                	try{
                		in.close();
                	}catch(Exception e){
                		e.printStackTrace();
                	}
                }
            }
            
            try{
            	shutdownServer.close();
            }catch(Exception ex){
            	LOGGER.error( ex.getMessage(), ex );
            }
            
            LOGGER.info( "Shutdown listener down! " );
            System.exit(0);
            LOGGER.info( "Exit system! " );
        }
	}
	
}
